<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css">
  <link rel="stylesheet" href="/lib/pace/pace-theme-minimal.min.css">
  <script src="/lib/pace/pace.min.js"></script>

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"lanqilu.github.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":true},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":true,"scrollpercent":true},"bookmark":{"enable":false,"color":"#395ca3","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":false,"pangu":true,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="Spring框架">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring框架">
<meta property="og:url" content="https://lanqilu.github.io/2020/03/21/Spring/Spring%E6%A1%86%E6%9E%B6/index.html">
<meta property="og:site_name" content="Halo">
<meta property="og:description" content="Spring框架">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://img.whl123456.top/image/ApplicationContext.png">
<meta property="og:image" content="e:%5CPictures%5Cblogimg%5CSpring%E6%A1%86%E6%9E%B6.assets%5CBeanFactory.png">
<meta property="og:image" content="e:%5CPictures%5Cblogimg%5CSpring%E6%A1%86%E6%9E%B6.assets%5CBean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.svg">
<meta property="og:image" content="http://img.whl123456.top/image/Spring%E6%A1%86%E6%9E%B6.png">
<meta property="article:published_time" content="2020-03-21T12:11:20.000Z">
<meta property="article:modified_time" content="2020-07-31T09:03:49.596Z">
<meta property="article:author" content="Lanqilu">
<meta property="article:tag" content="Spring">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://img.whl123456.top/image/ApplicationContext.png">

<link rel="canonical" href="https://lanqilu.github.io/2020/03/21/Spring/Spring%E6%A1%86%E6%9E%B6/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>Spring框架 | Halo</title>
  
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-161500949-1"></script>
    <script data-pjax>
      if (CONFIG.hostname === location.hostname) {
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-161500949-1');
      }
    </script>


  <script data-pjax>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?256151d1651e9d73ec980b2fc69de8f6";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Halo</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签<span class="badge">39</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类<span class="badge">18</span></a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档<span class="badge">85</span></a>

  </li>
        <li class="menu-item menu-item-python">

    <a href="/categories/Python/" rel="section"><i class="fa fa-fw fa-code"></i>Python</a>

  </li>
        <li class="menu-item menu-item-java">

    <a href="/categories/Java/" rel="section"><i class="fa fa-fw fa-code"></i>Java</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://lanqilu.github.io/2020/03/21/Spring/Spring%E6%A1%86%E6%9E%B6/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="http://img.whl123456.top/image/avatar.jpg">
      <meta itemprop="name" content="Lanqilu">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Halo">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Spring框架
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-03-21 20:11:20" itemprop="dateCreated datePublished" datetime="2020-03-21T20:11:20+08:00">2020-03-21</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-07-31 17:03:49" itemprop="dateModified" datetime="2020-07-31T17:03:49+08:00">2020-07-31</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JavaEE/" itemprop="url" rel="index"><span itemprop="name">JavaEE</span></a>
                </span>
                  ，
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JavaEE/Spring/" itemprop="url" rel="index"><span itemprop="name">Spring</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <div class="note info no-icon">
            <p>Spring框架</p>
          </div>

<a id="more"></a>

<hr>
<h2 id="基础知识"><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h2><h3 id="程序的耦合"><a href="#程序的耦合" class="headerlink" title="程序的耦合"></a>程序的耦合</h3><p>耦合：程序间的依赖关系</p>
<p>包括：</p>
<ul>
<li>类之间的依赖</li>
<li>方法间的依赖</li>
</ul>
<p>解耦：降低程序间的依赖关系</p>
<p>实际开发中：应该做到：编译期不依赖，运行时才依赖。</p>
<p>解耦的思路：</p>
<ul>
<li>第一步：使用反射来创建对象，而避免使用new关键字。</li>
<li>第二步：通过读取配置文件来获取要创建的对象全限定类名</li>
</ul>
<h3 id="工厂模式"><a href="#工厂模式" class="headerlink" title="工厂模式"></a>工厂模式</h3><p>Bean：在计算机英语中，有可重用组件的含义。</p>
<p>JavaBean：用java语言编写的可重用组件。JavaBean &gt;  实体类</p>
<h2 id="Spring介绍"><a href="#Spring介绍" class="headerlink" title="Spring介绍"></a>Spring介绍</h2><p>创建Spring的目的就是用来<strong>替代更加重量级的的企业级Java技术</strong>，<strong>简化Java的开发</strong></p>
<ul>
<li>基于POJO轻量级和<strong>最小侵入式开发</strong></li>
<li>通过依赖注入和面向接口实现<strong>松耦合</strong></li>
<li><strong>基于切面</strong>和惯例进行声明式编程</li>
<li>通过切面和模板<strong>减少样板式代码</strong></li>
</ul>
<blockquote>
<p>POJO（Plain Ordinary Java Object）简单的Java对象，实际就是普通JavaBeans，是为了避免和EJB混淆所创造的简称。</p>
<p>JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean，类必须是具体的和公共的，并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性，set和get方法获取。众所周知，属性名称符合这种模式，其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。</p>
</blockquote>
<h2 id="侵入式概念"><a href="#侵入式概念" class="headerlink" title="侵入式概念"></a>侵入式概念</h2><p>Spring是一种非侵入式的框架</p>
<h3 id="侵入式"><a href="#侵入式" class="headerlink" title="侵入式"></a>侵入式</h3><p>对于EJB、Struts2等一些传统的框架，<strong>通常是要实现特定的接口，继承特定的类才能增强功能</strong>，<strong>改变了java类的结构</strong></p>
<h3 id="非侵入式"><a href="#非侵入式" class="headerlink" title="非侵入式"></a>非侵入式</h3><p>对于Hibernate、Spring等框架，<strong>对现有的类结构没有影响，就能够增强JavaBean的功能</strong></p>
<h2 id="Spring-IoC的概念"><a href="#Spring-IoC的概念" class="headerlink" title="Spring IoC的概念"></a>Spring IoC的概念</h2><p>Spring的IoC容器是整个Spring框架的核心和基础</p>
<h3 id="Spring-IoC-概述"><a href="#Spring-IoC-概述" class="headerlink" title="Spring IoC 概述"></a>Spring IoC 概述</h3><p>IoC的全程为Inversion of Control，中文常翻译为“控制反转”，让别人为你服务，是一种通过描述（在Java中可以是XML或者注解）并通过第三方去产生或获取特定对象的方式。</p>
<p>在Spring中实现控制反转的是IoC容器，实现方法是依赖注入</p>
<p><strong>对象的创建交给外部容器完成，这个就做控制反转。</strong></p>
<blockquote>
<p>IoC的思想最核心的地方在于，资源不由使用资源的双方管理，而由不使用资源的第三方管理，这可以带来很多好处。</p>
<p>第一，资源集中管理，实现资源的可配置和易管理。</p>
<p>第二，降低了使用资源双方的依赖程度，也就是我们说的耦合度</p>
</blockquote>
<h3 id="Spring-IoC容器"><a href="#Spring-IoC容器" class="headerlink" title="Spring IoC容器"></a>Spring IoC容器</h3><p>无论是创建对象、处理对象之间的依赖关系、对象创建的时间还是对象的数量，我们都是在Spring为我们提供的IoC容器上配置对象的信息就好了。</p>
<p>Spring IoC容器的设计主要是基于<code>BeanFactory</code>和<code>ApplicationContext</code>两个接口，其中<code>ApplicationContext</code>是<code>BeanFactory</code>的子接口之一。<code>BeanFactory</code>是Spring IoC容器所定义的最底层接口，而<code>ApplicationContext</code>是其高级接口之一，并且对<code>BeanFactory</code>功能做了许多有用的扩展，故在绝大数工作情况下，都会使用<code>ApplicationContext</code>作为Spring IoC容器。</p>
<p><img src="http://img.whl123456.top/image/ApplicationContext.png" alt="ApplicationContext"></p>
<h3 id="BeanFactory"><a href="#BeanFactory" class="headerlink" title="BeanFactory"></a>BeanFactory</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 5.2.6.RELEASE 源码</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">BeanFactory</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	String FACTORY_BEAN_PREFIX = <span class="string">"&amp;"</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function">Object <span class="title">getBean</span><span class="params">(String name)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line"></span><br><span class="line">	&lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(String name, Class&lt;T&gt; requiredType)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function">Object <span class="title">getBean</span><span class="params">(String name, Object... args)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line"></span><br><span class="line">	&lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(Class&lt;T&gt; requiredType)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line"></span><br><span class="line">	&lt;T&gt; <span class="function">T <span class="title">getBean</span><span class="params">(Class&lt;T&gt; requiredType, Object... args)</span> <span class="keyword">throws</span> BeansException</span>;</span><br><span class="line"></span><br><span class="line">	&lt;T&gt; <span class="function">ObjectProvider&lt;T&gt; <span class="title">getBeanProvider</span><span class="params">(Class&lt;T&gt; requiredType)</span></span>;</span><br><span class="line"></span><br><span class="line">	&lt;T&gt; <span class="function">ObjectProvider&lt;T&gt; <span class="title">getBeanProvider</span><span class="params">(ResolvableType requiredType)</span></span>;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">containsBean</span><span class="params">(String name)</span></span>;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">isSingleton</span><span class="params">(String name)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">isPrototype</span><span class="params">(String name)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">isTypeMatch</span><span class="params">(String name, ResolvableType typeToMatch)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">isTypeMatch</span><span class="params">(String name, Class&lt;?&gt; typeToMatch)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Nullable</span></span><br><span class="line">	Class&lt;?&gt; getType(String name) <span class="keyword">throws</span> NoSuchBeanDefinitionException;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Nullable</span></span><br><span class="line">	Class&lt;?&gt; getType(String name, <span class="keyword">boolean</span> allowFactoryBeanInit) <span class="keyword">throws</span> NoSuchBeanDefinitionException;</span><br><span class="line"></span><br><span class="line">	String[] getAliases(String name);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><img src="E:%5CPictures%5Cblogimg%5CSpring%E6%A1%86%E6%9E%B6.assets%5CBeanFactory.png" alt="BeanFactory"></p>
<ul>
<li><code>getBean</code>的方法多用于获取配置给Spring IoC容器的Bean。从参数类型来看可以是字符串，也可以是<code>Class</code>类型，由于<code>Class</code>类型可以扩展接口也可以继承父类，所以在一定程度上会存在使用父类类型无法准确获得实例的异常。</li>
<li><code>isSingleton</code>用于判断是否为单例，如果判断为真，其意思是该Bean在容器中是作为一个唯一单例存在的。而<code>isPrototype</code>则相反，如果判断为真，意思是当你从容器中获取Bean，容器就为你生成一个新的实例。在默认情况下，Spring会为Bean创建一个单例，也就是默认情况下<code>isSingleton</code>返回true，而<code>isPrototype</code>返回false。</li>
<li><code>getAliases</code>方法是获取别名的方法。</li>
</ul>
<h3 id="容器的初始化和依赖注入"><a href="#容器的初始化和依赖注入" class="headerlink" title="容器的初始化和依赖注入"></a>容器的初始化和依赖注入</h3><p>Bean的定义和初始化在Spring IoC容器中的是两大步骤，它是先定义，然后初始化和依赖注入。</p>
<p>Bean的定义分为3步：</p>
<ul>
<li>Resource定位：这步是Spring IoC容器根据开发者的配置，进行资源定位，在Spring的开发中，通过XML或者注解都是十分常见的方式，定位的内容是由开发者所提供。</li>
<li>BeanDefinition的载入：将BeanDefinition的信息保存到Bean定义中，此时不会创建Bean的实例。</li>
<li>BeanDefinition的注册：将BeanDefinition的信息发布到Spring IoC容器中，但此时仍旧没有对应的Bean的实例创建。</li>
</ul>
<p>完成以上3步Bean就在Spring IoC容器中被定义了，而没有初始化，更没有完成依赖注入，也就是没有注入其配置的资源给Bean。</p>
<p>对于初始化和依赖注入，Spring Bean还有一个配置选项<code>lazy-init</code>，其含义就是是否初始化Spring Bean。在没有任何配置的情况下，它的默认值为default，实际值为false，也就是Spring IoC默认会自动初始化Bean。如果将其设置为true，那么只有当我们使用Spring IoC容器的<code>getBean</code>方法获取它时，它才会进行Bean的初始化，完成依赖注入。</p>
<h3 id="Bean的生命周期"><a href="#Bean的生命周期" class="headerlink" title="Bean的生命周期"></a>Bean的生命周期</h3><p>对于Bean而言，在容器中存在其生命周期，它的初始化和销毁也需要一个过程。</p>
<p><img src="E:%5CPictures%5Cblogimg%5CSpring%E6%A1%86%E6%9E%B6.assets%5CBean%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.svg" alt="Bean的生命周期"></p>
<ul>
<li>如果Bean实现了<code>BeanNameAware</code>接口的<code>setBeanName</code>方法，那么它就会调用这个方法</li>
<li>如果Bean实现了<code>BeanFactoryAware</code>接口的<code>setBeanFactory</code>方法，那么它就会调用这个方法</li>
<li>如果Bean实现了<code>ApplicationContextAware</code>接口的<code>setApplicationContext</code>方法，且Spring IoC容器也必须是一个<code>ApplicationContext</code>接口的实现类，那么才会调用这个方法，否则是不调用</li>
<li>如果Bean实现了<code>BeanPostProcessor</code>接口的<code>postProcessBeforeInitialization</code>方法，那么它就会调用这个方法（注意它针对全部Bean而言）</li>
<li>如果Bean实现了<code>InitializingBean</code>接口的<code>afterPropertiesSet</code>方法，那么它就会调用这个方法</li>
<li>如果Bean自定义了初始化方法，他就会调用已定义的初始化方法。</li>
<li>如果Bean实现了<code>BeanPostProcessor</code>接口的<code>postProcessAfterInitialization</code>方法，完成了这些调用，这个时候Bean就完成了初始化，那么Bean就存在Spring IoC的容器中，使用者就可以从中获取Bean的服务</li>
</ul>
<p>当服务器正常关闭，或者遇到其他关闭Spring IoC容器的事件，它就会调用对应的方法完成Bean的销毁，其步骤入下：</p>
<ul>
<li>如果Bean实现了接口<code>DisposableBean</code>的<code>destory</code>方法，那么就会调用它</li>
<li>如果定义了自定义销毁方法，那么就会调用它</li>
</ul>
<h2 id="装配Spring-Bean"><a href="#装配Spring-Bean" class="headerlink" title="装配Spring Bean"></a>装配Spring Bean</h2><h3 id="依赖注入的3种方式"><a href="#依赖注入的3种方式" class="headerlink" title="依赖注入的3种方式"></a>依赖注入的3种方式</h3><p>那么对象的对象之间的依赖关系Spring是怎么做的呢？？<strong>依赖注入（Dependency Injection，DI）</strong></p>
<ul>
<li><strong>Spring使用依赖注入来实现对象之间的依赖关系</strong></li>
<li><strong>在创建完对象之后，对象的关系处理就是依赖注入</strong></li>
</ul>
<p>一般而言，依赖注入可以分为3种方式：</p>
<ul>
<li>构造器注入</li>
<li>setter注入</li>
<li>接口注入</li>
</ul>
<p>构造器注入和setter注入是主要的方式，而接口注入是从别的地方注入的方式。</p>
<h4 id="构造器注入"><a href="#构造器注入" class="headerlink" title="构造器注入"></a>构造器注入</h4><p>顾名思义，构造器注入依赖于构造方法实现，就是被注入对象可以通过在其构造方法中声明依赖对象的参数列表，让外部（通常是IoC容器）知道它需要哪些依赖对象。</p>
<p>在大部分情况下，我们通过类的构造方法来创建类对象，Spring也可以采用反射的方式通过使用构造方法来完成注入，这就是构造器注入的原理。</p>
<p>在配置文件中，<code>constructor-arg</code>元素用于定义类构造方法的参数。包括index方式、type方式和name方式</p>
<h4 id="setter方法注入"><a href="#setter方法注入" class="headerlink" title="setter方法注入"></a>setter方法注入</h4><p>setter注入式Spring中最主流的注入方式，它利用Java Bean规范所定义的setter方法来完成注入，灵活且可读性高。</p>
<p>它消除了使用构造器护注入时出现多个参数的可能性，首先可以把构造方法声明为无参数的，然后使用setter注入为其设置对应的值，其实也是通过Java反射技术实现的。</p>
<h4 id="三种注入方式的比较"><a href="#三种注入方式的比较" class="headerlink" title="三种注入方式的比较"></a>三种注入方式的比较</h4><ul>
<li>接口注入。从注入方式的使用上来说，接口注入是现在不甚提倡的一种方式，基本处于“退役状态”。因为它强制被注入对象实现不必要的接口，带有侵入性。而构造方法注入和setter方法注入则不需要如此。</li>
<li>构造方法注入。这种注入方式的优点就是，对象在构造完成之后，即已进入就绪状态，可以马上使用。缺点就是，当依赖对象比较多的时候，构造方法的参数列表会比较长。而通过反射构造对象的时候，对相同类型的参数的处理会比较困难，维护和使用上也比较麻烦。而且在Java中，构造方法无法被继承，无法设置默认值。对于非必须的依赖处理，可能需要引入多个构造方法，而参数数量的变动可能造成维护上的不便。</li>
<li>setter方法注入。因为方法可以命名，所以setter方法注入在描述性上要比构造方法注入好一些。<br>另外，seter方法可以被继承，允许设置默认值，而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。</li>
<li>综上所述，构造方法注入和setter方法注入因为其侵入性较弱，且易于理解和使用，所以是现在使用最多的注入方式</li>
</ul>
<h3 id="装配Bean概述"><a href="#装配Bean概述" class="headerlink" title="装配Bean概述"></a>装配Bean概述</h3><p>将开发的Bean装配到Spring IoC容器中，在大部分场景下使用<code>ApplicationContext</code>的具体实现类，因为对应的Spring IoC容器功能强大。</p>
<p>而在Spring中提供了3种方法进行配置：</p>
<ul>
<li>在XML中显示配置</li>
<li>在Java的接口和类中实现配置</li>
<li>隐式Bean的发现机制和自动装配原则</li>
</ul>
<p>在学习和工作中，这3种方式都会被用到，且常常混合使用，对于怎么选择有以下几点建议：</p>
<ul>
<li>基于约定优于配置的原则，最优先的应该时通过隐式Bean的发现机制和自动装配的原则。这样的好处是减少程序开发者的决定权，简单又不失灵活。</li>
<li>在没有办法使用自动装配原则的情况下应该优先考虑Java接口和类中实现配置，这样的好处是避免XMl配置的泛滥，也更为容易。这种场景典型了例子是一个父类有多个子类，比如学术类有两个子类：男生类和女生类，通过IoC容器初始化一个学术类，容器将无法知道使用哪个子类去初始化，这个时候可以使用Java的注解配置去指定。</li>
<li>上述方法都无法使用的情况下，那么只能选择XML去配置Sping IoC容器。由于现实中常常用到第三方的类库，有些类并不是我们开发的，我们无法修改里面的代码，这个时候就通过XML的方式配置使用了。</li>
</ul>
<h3 id="通过XML配置装配Bean"><a href="#通过XML配置装配Bean" class="headerlink" title="通过XML配置装配Bean"></a>通过XML配置装配Bean</h3><p>使用XML装配Bean需要定义对应的XML，这里需要引入对应的XML模式（XSD）文件，这些文件会定义配置Spring Bean的一些元素</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">                           http://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line">    </span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>上述代码中引入了一个<code>beans</code>的定义，它是一个根元素，而XSD文件也被引入了，这样它所定义的元素将可以定义对应的Spring Bean</p>
<h4 id="装配简易值"><a href="#装配简易值" class="headerlink" title="装配简易值"></a>装配简易值</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"source"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo2.Source"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"fruit"</span> <span class="attr">value</span>=<span class="string">"橙汁"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"size"</span> <span class="attr">value</span>=<span class="string">"大杯"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"sugar"</span> <span class="attr">value</span>=<span class="string">"少糖"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"juiceMaker2"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo2.JuiceMaker2"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"beverageShop"</span> <span class="attr">value</span>=<span class="string">"贡茶"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"source"</span> <span class="attr">ref</span>=<span class="string">"source"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ul>
<li><code>id</code>属性是Spring找到这个Bean的编号，不过<code>id</code>不是一个必须的属性，如果没有声明它，那么Spring会采用<code>全限定名#{number}</code>的格式生成编号。例如：没有声明<code>id=&quot;source&quot;</code>，那么Spring为其生成的编号就是<code>&quot;top.whl.pojo2.Source#0&quot;</code>。当第二次声明没有id的属性的Bean时，编号就是<code>&quot;top.whl.pojo2.Source#1&quot;</code>，以此类推。</li>
<li><code>class</code> 是一个类的全限定名</li>
<li><code>property</code> 元素是定义类的属性，其中<code>name</code>属性定义的是属性名称，而<code>value</code>是其值</li>
<li><code>ref</code> 引用Spring中创建好的对象</li>
</ul>
<h4 id="装配集合"><a href="#装配集合" class="headerlink" title="装配集合"></a>装配集合</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"list"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-list-1<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-list-2<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-list-3<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>List</code>属性为对应的<code>&lt;list&gt;</code>元素进行装配，然后通过多个<code>&lt;value&gt;</code>元素设值</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"map"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"key1"</span> <span class="attr">value</span>=<span class="string">"value-key-1"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"key2"</span> <span class="attr">value</span>=<span class="string">"value-key-2"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"key3"</span> <span class="attr">value</span>=<span class="string">"value-key-3"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>Map</code>属性为对应的<code>map</code>元素进行装配，然后通过多个<code>&lt;entry&gt;</code>元素设值，其中<code>entry</code>包含一个键（key）和一个值（value）的设置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"props"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">props</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"prop1"</span>&gt;</span>value-prop-1<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"prop2"</span>&gt;</span>value-prop-2<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"prop3"</span>&gt;</span>value-prop-3<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>Properties</code>属性，为对应的<code>&lt;props&gt;</code>元素进行装配，通过多个<code>&lt;prop&gt;</code>元素设置，其中<code>&lt;prop&gt;</code>元素有一个必填属性key，然后在之间设置值</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"set"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-set-1<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-set-2<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-set-3<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>Set</code>属性为对应的<code>&lt;set&gt;</code>元素进行装配，然后通过多个<code>&lt;value&gt;</code>元素设置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"array"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-array-1<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-array-2<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">value</span>&gt;</span>value-array-3<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>对于数组而言，可以使用<code>&lt;array&gt;</code>设置值，然后通过多个<code>&lt;value&gt;</code>元素设值。</p>
<hr>
<p>有些时候需要更为复杂的装载，比如一个List可以是一系列的对象，又如Map集合类，键可以 是一个类的对象，而值也要是一个类的对象。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"list"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">"role1"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">"role2"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>List</code>属性使用<code>&lt;list&gt;</code>元素定义注入，使用多个<code>&lt;ref&gt;</code>元素的Bean属性去引用之前定义好的Bean</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"map"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key-ref</span>=<span class="string">"role2"</span> <span class="attr">value</span>=<span class="string">"user1"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key-ref</span>=<span class="string">"role2"</span> <span class="attr">value</span>=<span class="string">"user2"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>Map</code>属性使用<code>&lt;map&gt;</code>元素定义注入，使用多个<code>&lt;enty&gt;</code>元素的<code>key-ref</code>属性去引用之前定义好的Bean做键，而用<code>value-ref</code>属性去引用之前定义好的Bean做值</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"set"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">"role1"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ref</span> <span class="attr">bean</span>=<span class="string">"role2"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>Set</code>属性使用<code>&lt;set&gt;</code>元素定义注入，使用多个<code>&lt;ref&gt;</code>元素的Bean去引用之前定义好的Bean</p>
<h4 id="命名空间装配"><a href="#命名空间装配" class="headerlink" title="命名空间装配"></a>命名空间装配</h4><h3 id="通过注解装配Bean"><a href="#通过注解装配Bean" class="headerlink" title="通过注解装配Bean"></a>通过注解装配Bean</h3><p>使用注解的方式可以减少XML的配置，注解功能更为强大，它既能实现XML的功能，也提供了自动装配的功能，采用了自动装配后，程序员所需要做的决断就少了，更加有利于程序的开发，这就是“约定优于配置”的开发原则。</p>
<p>在Spring中，它提供了两种方式来让Spring IoC容器发现Bean</p>
<ul>
<li>组件扫描：通过定义资源的方式，让Sprnig IoC容器扫描对应的包，从而把Bean装配进来。</li>
<li>自动装配：通过注解定义，使得一些依赖关系可以通过注解完成</li>
</ul>
<h4 id="使用-Component装配Bean"><a href="#使用-Component装配Bean" class="headerlink" title="使用@Component装配Bean"></a>使用<code>@Component</code>装配Bean</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span>(value = <span class="string">"role"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Role</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"1"</span>)</span><br><span class="line">    <span class="keyword">private</span> Long id;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"role_name_1"</span>)</span><br><span class="line">    <span class="keyword">private</span> String roleName;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"role_note_1"</span>)</span><br><span class="line">    <span class="keyword">private</span> String note;</span><br><span class="line">    <span class="comment">/**** setter and getter ****/</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>注解<code>@Component</code>代表Spring IoC会把这个类扫描生成Bean实例，而其中的<code>value</code>属性代表这个类在Spring中的id，就相当于XML方式定义的Bean的id，也可以简写成<code>@Component(“role”)</code>，甚至直接写成<code>@Component</code>，对于不写的，Spring IoC容器就默认为类名，但是以首字母小写的形式作为id，为其生成对象，配置到容器中。</li>
<li>注解<code>@Value</code>代表是是值的注入，这里只是简单注入一些值，其中id是一个long型，注入的时候Spring会为其转化类型</li>
</ul>
<p>现在有了这个类，但是还不能进行测试，因为Spring IoC并不知道需要去哪里扫描对象，这个时候可以在同一个包下创建一个Java Config类来告诉它</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ComponentScan</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PojoConfig</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个类十分简单但要注意<code>@ComponentScan</code>代表进行扫描，默认是扫描当前包的路径，POJO的包名和它保持一致才能进行扫描，否则不行。</p>
<p>接下来通过Spring定义好的Spring IoC容器实现类<code>AnnotationConfigApplicationContext</code>去生成IoC容器</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Pojo2Text</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        AnnotationConfigApplicationContext context = <span class="keyword">new</span> AnnotationConfigApplicationContext(PojoConfig<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        Role role = context.getBean(Role<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        System.out.println(<span class="string">"role.getId() = "</span> + role.getId());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>由此可以看出两个明显的弊端：</p>
<ul>
<li>对于<code>@ComponentScan</code>注解，它只是扫描所在包的Java类，但更多的时候需要的是可以扫描所指定的类</li>
<li>上面只注入了一些简单的值，而没有注入对象，同样在现实的开发中可以注入对象是十分重要的，也是常见的场景</li>
</ul>
<p><code>@ComponentScan</code>存在着两个配置项：</p>
<ul>
<li>第一个是<code>basePackages</code>，它是由base和package两个单词组成的，而package还使用了复数，意味着它可以配置一个Java包的数组，Spring会根据它的配置扫描对应的包和子包，将配置好的Bean装配起来</li>
<li>第二个是<code>basePackageClasses</code>，Class采用复数，意味着它可以配置多个类，Spring会根据配置的类所在的包，为包和子包进行扫描装配对应配置的Bean</li>
</ul>
<p>为验证<code>@ComponentScan</code>的配置项，首先定义一个接口</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> top.whl.service2;</span><br><span class="line"><span class="keyword">import</span> top.whl.pojo2.Role;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">RoleService</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">printRoleInfo</span><span class="params">(Role role)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用接口来编写一些操作类是Spring所推荐的，它可以将定义和实现相分离。接口的实现类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> top.whl.service2.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> top.whl.pojo2.Role;</span><br><span class="line"><span class="keyword">import</span> top.whl.service2.RoleService;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RoleServiceImpl</span> <span class="keyword">implements</span> <span class="title">RoleService</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">printRoleInfo</span><span class="params">(Role role)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"id = "</span> + role.getId());</span><br><span class="line">        System.out.println(<span class="string">"name = "</span> + role.getRoleName());</span><br><span class="line">        System.out.println(<span class="string">"note = "</span> + role.getNote());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>配置<code>@ComponentScan</code>指定包扫描</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> top.whl.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.ComponentScan;</span><br><span class="line"><span class="keyword">import</span> top.whl.pojo2.Role;</span><br><span class="line"><span class="keyword">import</span> top.whl.service2.RoleService;</span><br><span class="line"></span><br><span class="line"><span class="meta">@ComponentScan</span>(basePackageClasses = &#123;Role<span class="class">.<span class="keyword">class</span>, <span class="title">RoleService</span>.<span class="title">class</span>&#125;)</span></span><br><span class="line"><span class="class"><span class="title">public</span> <span class="title">class</span> <span class="title">ApplicationConfig</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>测试配置</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Service2Test</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        AnnotationConfigApplicationContext context = <span class="keyword">new</span> AnnotationConfigApplicationContext(ApplicationConfig<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"></span><br><span class="line">        Role role = context.getBean(Role<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        RoleService roleService = context.getBean(RoleService<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">        roleService.printRoleInfo(role);</span><br><span class="line">        context.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="自动装配——-Autowired"><a href="#自动装配——-Autowired" class="headerlink" title="自动装配——@Autowired"></a>自动装配——<code>@Autowired</code></h4><h3 id="Spring模块"><a href="#Spring模块" class="headerlink" title="Spring模块"></a>Spring模块</h3><p><strong>Spring可以分为6大模块</strong>：</p>
<ul>
<li><strong>Spring Core</strong>： Spring的核心功能： IOC容器, 解决对象创建及依赖关系</li>
<li><strong>Spring Web</strong>： Spring对web模块的支持。<ul>
<li>可以与struts整合,让struts的action创建交给spring</li>
<li>spring mvc模式</li>
</ul>
</li>
<li><strong>Spring DAO</strong>： Spring 对jdbc操作的支持 【JdbcTemplate模板工具类】</li>
<li><strong>Spring ORM</strong>： Spring对orm的支持：<ul>
<li>既可以与hibernate整合，【session】</li>
<li>也可以使用spring的对hibernate操作的封装</li>
</ul>
</li>
<li><strong>Spring AOP</strong>： 切面编程</li>
<li><strong>SpringEE</strong>： Spring 对JavaEE其他模块的支持</li>
</ul>
<p><img src="http://img.whl123456.top/image/Spring%E6%A1%86%E6%9E%B6.png" alt="Sping"></p>
<h3 id="Spring-Core模块"><a href="#Spring-Core模块" class="headerlink" title="Spring Core模块"></a>Spring Core模块</h3><p>核心容器</p>
<h2 id="HelloSpirng"><a href="#HelloSpirng" class="headerlink" title="HelloSpirng"></a>HelloSpirng</h2><blockquote>
<p>对应源码实例为：HelloSpring</p>
</blockquote>
<h2 id="applicationContext-xml的配置"><a href="#applicationContext-xml的配置" class="headerlink" title="applicationContext.xml的配置"></a>applicationContext.xml的配置</h2><h3 id="别名"><a href="#别名" class="headerlink" title="别名"></a>别名</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">alias</span> <span class="attr">name</span>=<span class="string">"原名"</span> <span class="attr">alias</span>=<span class="string">"别名"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>原名和别名都可以被Spring创建，获取到原名对应的对象</p>
<h3 id="Bean的配置"><a href="#Bean的配置" class="headerlink" title="Bean的配置"></a>Bean的配置</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">name</span>=<span class="string">"user3,u3"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"name"</span> <span class="attr">value</span>=<span class="string">"whl_property"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>id</code>：bean的唯一标识符，是java类中的对象名</p>
<p><code>class</code>：bean对象对应的全限定名：包名+类名</p>
<p><code>name</code>：别名，可以同时取多个别名（用逗号、空格或分号分开），比<code>alias</code>更高级</p>
<h3 id="import"><a href="#import" class="headerlink" title="import"></a>import</h3><p>用于团队开发，将多个配置文件导入合并</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">import</span> <span class="attr">resource</span>=<span class="string">"beans2.xml"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>对应源码实例为：SpringIoC02</p>
</blockquote>
<h2 id="依赖注入（DI）"><a href="#依赖注入（DI）" class="headerlink" title="依赖注入（DI）"></a>依赖注入（DI）</h2><h3 id="构造器注入-1"><a href="#构造器注入-1" class="headerlink" title="构造器注入"></a>构造器注入</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">name</span>=<span class="string">"user3,u3 u4"</span>&gt;</span></span><br><span class="line">	<span class="comment">&lt;!--index方式--&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">index</span>=<span class="string">"0"</span> <span class="attr">value</span>=<span class="string">"whl_constructor-arg_index"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">name</span>=<span class="string">"user3,u3 u4"</span>&gt;</span></span><br><span class="line">	<span class="comment">&lt;!--type方式--&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">type</span>=<span class="string">"java.lang.String"</span> <span class="attr">value</span>=<span class="string">"whl_constructor-arg_type"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">name</span>=<span class="string">"user3,u3 u4"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">constructor-arg</span> <span class="attr">name</span>=<span class="string">"name"</span> <span class="attr">value</span>=<span class="string">"whl_constructor-arg_name"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>对应源码实例为：SpringIoC02</p>
</blockquote>
<h3 id="Set方式注入"><a href="#Set方式注入" class="headerlink" title="Set方式注入"></a>Set方式注入</h3><p>需要类中有Set方法</p>
<ul>
<li>依赖：bean对象的创建依赖于容器</li>
<li>注入：bean对象中的所有属性，由容器来注入</li>
</ul>
<p>测试对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Student</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> Address address;</span><br><span class="line">    <span class="keyword">private</span> String[] books;</span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; hobbies;</span><br><span class="line">    <span class="keyword">private</span> Map&lt;String,String&gt; card;</span><br><span class="line">    <span class="keyword">private</span> Set&lt;String&gt; games;</span><br><span class="line">    <span class="keyword">private</span> String oh;</span><br><span class="line">    <span class="keyword">private</span> Properties info;</span><br><span class="line">    <span class="comment">//省略getter、setter和toString方法代码</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>测试类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Text01</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//CPX</span></span><br><span class="line">        ClassPathXmlApplicationContext context = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"applicationContext.xml"</span>);</span><br><span class="line">        Student student = (Student) context.getBean(<span class="string">"student"</span>);</span><br><span class="line">        System.out.println(<span class="string">"student.toString() = "</span> + student.toString());</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>注入方式</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"address"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.Address"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"address"</span> <span class="attr">value</span>=<span class="string">"浙江"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"student"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.Student"</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--01 普通值注入直接使用value--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"name"</span> <span class="attr">value</span>=<span class="string">"whl"</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--02 Bean注入使用ref--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"address"</span> <span class="attr">ref</span>=<span class="string">"address"</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--03 数组注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"books"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">array</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>红楼梦<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>西游记<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>水浒传<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>三国演义<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">array</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--04 List注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"hobbies"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>篮球<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>足球<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>乒乓球<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>羽毛球<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--05 Map注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"card"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">map</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"学号"</span> <span class="attr">value</span>=<span class="string">"000000"</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"身份证号"</span> <span class="attr">value</span>=<span class="string">"000000"</span>/&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"银行卡号"</span> <span class="attr">value</span>=<span class="string">"000000"</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">map</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--06 Set注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"games"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">set</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>LOL<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">value</span>&gt;</span>CS<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--07 null注入--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"oh"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">null</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--08 Properties--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"info"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">props</span> &gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"姓名"</span>&gt;</span>whl<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"年龄"</span>&gt;</span>18<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"性别"</span>&gt;</span>男<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"driver"</span>&gt;</span>000<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"url"</span>&gt;</span>000<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"username"</span>&gt;</span>000<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"password"</span>&gt;</span>000<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">props</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>对应源码实例：SpringDI</p>
</blockquote>
<h3 id="拓展方式注入"><a href="#拓展方式注入" class="headerlink" title="拓展方式注入"></a>拓展方式注入</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       </span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:p</span>=<span class="string">"http://www.springframework.org/schema/p"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:c</span>=<span class="string">"http://www.springframework.org/schema/c"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">        https://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--p命名空间注入直接注入属性的值 property--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">p:name</span>=<span class="string">"whl"</span> <span class="attr">p:age</span>=<span class="string">"18"</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--c命名空间注入 constructor--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user2"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">c:age</span>=<span class="string">"19"</span> <span class="attr">c:name</span>=<span class="string">"whl02"</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>测试类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test02</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">    ClassPathXmlApplicationContext context = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"user.xml"</span>);</span><br><span class="line">    User user = context.getBean(<span class="string">"user"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    System.out.println(<span class="string">"user = "</span> + user);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test03</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">    ClassPathXmlApplicationContext context = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"user.xml"</span>);</span><br><span class="line">    User user2 = context.getBean(<span class="string">"user2"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    System.out.println(<span class="string">"user2 = "</span> + user2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>测试对象User类中需要设置无参构造和有参构造才能使用c命名空间</p>
</blockquote>
<h2 id="Bean作用域"><a href="#Bean作用域" class="headerlink" title="Bean作用域"></a>Bean作用域</h2><table>
<thead>
<tr>
<th align="left">Scope</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-singleton" target="_blank" rel="noopener">singleton</a></td>
<td align="left">(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.</td>
</tr>
<tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-prototype" target="_blank" rel="noopener">prototype</a></td>
<td align="left">Scopes a single bean definition to any number of object instances.</td>
</tr>
<tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-request" target="_blank" rel="noopener">request</a></td>
<td align="left">Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring <code>ApplicationContext</code>.</td>
</tr>
<tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-session" target="_blank" rel="noopener">session</a></td>
<td align="left">Scopes a single bean definition to the lifecycle of an HTTP <code>Session</code>. Only valid in the context of a web-aware Spring <code>ApplicationContext</code>.</td>
</tr>
<tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-application" target="_blank" rel="noopener">application</a></td>
<td align="left">Scopes a single bean definition to the lifecycle of a <code>ServletContext</code>. Only valid in the context of a web-aware Spring <code>ApplicationContext</code>.</td>
</tr>
<tr>
<td align="left"><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-websocket-scope" target="_blank" rel="noopener">websocket</a></td>
<td align="left">Scopes a single bean definition to the lifecycle of a <code>WebSocket</code>. Only valid in the context of a web-aware Spring <code>ApplicationContext</code>.</td>
</tr>
</tbody></table>
<h3 id="singleton单例模式"><a href="#singleton单例模式" class="headerlink" title="singleton单例模式"></a>singleton单例模式</h3><p>无论使用多少个Bean只有一个实例被创建，默认实现</p>
<p>测试类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test04</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ClassPathXmlApplicationContext context = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"user.xml"</span>);</span><br><span class="line">    User user2 = context.getBean(<span class="string">"singleton"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    User user3 = context.getBean(<span class="string">"singleton"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    System.out.println(user3==user2);<span class="comment">//true</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>显式创建</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"singleton"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">scope</span>=<span class="string">"singleton"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="prototype原型模式"><a href="#prototype原型模式" class="headerlink" title="prototype原型模式"></a>prototype原型模式</h3><p>每次从容器（context）中getBean都会产生新对象</p>
<p>创建</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"prototype"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.User"</span> <span class="attr">scope</span>=<span class="string">"prototype"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<p>测试类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test05</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ClassPathXmlApplicationContext context = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"user.xml"</span>);</span><br><span class="line">    User user2 = context.getBean(<span class="string">"prototype"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    User user3 = context.getBean(<span class="string">"prototype"</span>, User<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line">    System.out.println(user3==user2);<span class="comment">//false</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>对应源码实例：SpringDI</p>
</blockquote>
<h3 id="其余"><a href="#其余" class="headerlink" title="其余"></a>其余</h3><p>其余在Web开发中使用</p>
<h2 id="Bean的自动装配"><a href="#Bean的自动装配" class="headerlink" title="Bean的自动装配"></a>Bean的自动装配</h2><p>3种装配方式：</p>
<ul>
<li>在xml中显式配置</li>
<li>在java中显式配置</li>
<li>隐式的自动装配</li>
</ul>
<h3 id="ByName"><a href="#ByName" class="headerlink" title="ByName"></a>ByName</h3><p>自动在容器上下文中查找和对象set后对应的bean的id，id唯一且与set方法对应</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"person2"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.Person"</span> <span class="attr">autowire</span>=<span class="string">"byName"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="ByType"><a href="#ByType" class="headerlink" title="ByType"></a>ByType</h3><p>自动在容器上下文中查找和对象属性相同的bean，class唯一，可以省略bean的id</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"person3"</span> <span class="attr">class</span>=<span class="string">"top.whl.pojo.Person"</span> <span class="attr">autowire</span>=<span class="string">"byType"</span>/&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="注解"><a href="#注解" class="headerlink" title="注解"></a>注解</h3><p>xml中导入context约束和开启注解支持</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">"http://www.springframework.org/schema/context"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">        https://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">        http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="tag"><span class="string">        https://www.springframework.org/schema/context/spring-context.xsd"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:annotation-config</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>类中属性和Setter方法中开启注解，在类中可以不用写Set方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> Cat cat;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> Dog dog;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="comment">//省略getter、setter和toString方法代码</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>@Autowired(required = true)</code>默认为true，如果设置<code>@Autowired(required = false)</code>，什么对象可以为null</p>
<p>但Bean中一个类配置多个id时使用<code>@Qualifier(value = &quot;对应id&quot;)</code>配合<code>@Autowired</code>可以指定bean，类型需要对应</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Autowired</span></span><br><span class="line"><span class="meta">@Qualifier</span>(value = <span class="string">"dog2"</span>)</span><br><span class="line"><span class="keyword">private</span> Dog dog;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>对应源码实例：Autowire</p>
</blockquote>
<h2 id="使用注解开发"><a href="#使用注解开发" class="headerlink" title="使用注解开发"></a>使用注解开发</h2><p><code>@Autowired</code>：自动装配，放在属性前面</p>
<p><code>@Nullable</code>：表示字段可以为空，放在形参前面</p>
<p><code>@Resource</code>：Java中的注解，用于自动装配，Java11移除</p>
<p><code>@Component</code>：被扫描类，放在类前，配合Bean中<code>&lt;context:component-scan base-package=&quot;包名&quot;/&gt;</code>使用，等价于<code>&lt;bean id=&quot;&quot; class=&quot;&quot;/&gt;</code></p>
<p><code>@Value(&quot;值&quot;)</code>：等价于<code>&lt;property name=&quot;&quot; value=&quot;&quot;&gt;</code>，复杂值推荐走配置文件，放在属性或对应Set方法前</p>
<h3 id="前提配置bean"><a href="#前提配置bean" class="headerlink" title="前提配置bean"></a>前提配置bean</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:context</span>=<span class="string">"http://www.springframework.org/schema/context"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">        https://www.springframework.org/schema/beans/spring-beans.xsd</span></span></span><br><span class="line"><span class="tag"><span class="string">        http://www.springframework.org/schema/context</span></span></span><br><span class="line"><span class="tag"><span class="string">        https://www.springframework.org/schema/context/spring-context.xsd"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!--扫描指定目录下的包，使注解生效--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">"top.whl"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context:annotation-config</span>/&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="属性注入"><a href="#属性注入" class="headerlink" title="属性注入"></a>属性注入</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">//    @Value("WHL")</span></span><br><span class="line">    <span class="keyword">public</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"WHL1"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="衍生的注解"><a href="#衍生的注解" class="headerlink" title="衍生的注解"></a>衍生的注解</h3><p><code>@Component</code>有几个衍生注解，在Web开发中，按照MVC结构分层</p>
<ul>
<li>DAO：使用<code>@Repository</code></li>
<li>Service：使用<code>@Service</code></li>
<li>Controller：使用<code>@Controller</code></li>
</ul>
<p>以上注解功能同<code>@Component</code></p>
<h3 id="自动装配"><a href="#自动装配" class="headerlink" title="自动装配"></a>自动装配</h3><p><code>@Autowired</code>：自动装配，放在属性前面</p>
<p><code>@Nullable</code>：表示字段可以为空，放在形参前面</p>
<p><code>@Resource</code>：Java中的注解，用于自动装配，Java11移除</p>
<p>详见Bean的自动装配</p>
<h3 id="作用域"><a href="#作用域" class="headerlink" title="作用域"></a>作用域</h3><p><code>@Scope(&quot;XXX&quot;)</code>详见Bean作用域</p>
<blockquote>
<p>对应源码实例：Annotation</p>
</blockquote>
<h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><ul>
<li>使用xml用来管理Bean</li>
<li>使用注解来完成属性注入</li>
</ul>
<h2 id="使用Java的方式配置Bean"><a href="#使用Java的方式配置Bean" class="headerlink" title="使用Java的方式配置Bean"></a>使用Java的方式配置Bean</h2><p>JavaConfig</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"WHL"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"User&#123;"</span> +</span><br><span class="line">                <span class="string">"name='"</span> + name + <span class="string">'\''</span> +</span><br><span class="line">                <span class="string">'&#125;'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan</span>(<span class="string">"top.whl"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Config01</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> User <span class="title">getUser</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> User();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="设计模式"><a href="#设计模式" class="headerlink" title="设计模式"></a>设计模式</h2><h3 id="静态代理"><a href="#静态代理" class="headerlink" title="静态代理"></a>静态代理</h3><p>代理的好处</p>
<ul>
<li><p>可以使真实角色的操作更加纯粹!不用去关注一些公共的业务</p>
</li>
<li><p>公共也就就交给代理角色!实现了业务的分工!</p>
</li>
<li><p>公共业务发生扩展的时候，方便集中管理!</p>
</li>
</ul>
<p>缺点</p>
<ul>
<li>一个真实角色就会产生1个代理角色</li>
<li>代码量会翻倍开发效率会变低</li>
</ul>
<p>接口</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Rent</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rent</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>真实角色</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Host</span> <span class="keyword">implements</span> <span class="title">Rent</span></span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"房东出租房子"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>代理</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Proxy</span> <span class="keyword">implements</span> <span class="title">Rent</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Host host;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Proxy</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Proxy</span><span class="params">(Host host)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.host = host;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        host.rent();</span><br><span class="line">        fee();</span><br><span class="line">        sign();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fee</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"收小费"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sign</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"签合同"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>客户端访问代理角色</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Host host = <span class="keyword">new</span> Host();</span><br><span class="line">        Proxy proxy = <span class="keyword">new</span> Proxy(host);</span><br><span class="line">        proxy.rent();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在不改变真实角色的代码的前提下增加功能</p>
<blockquote>
<p>对应实例源码：proxy</p>
</blockquote>
<h3 id="动态代理"><a href="#动态代理" class="headerlink" title="动态代理"></a>动态代理</h3><p>在静态代理的优点基础上还有</p>
<ul>
<li>一个动态代理可以代理多个类，只要改变接口</li>
</ul>
<p>实现方式</p>
<ul>
<li><p>基于接口的动态代理（JDK反射）</p>
</li>
<li><p>基于类的动态代理（CGLib）</p>
</li>
<li><p>Java字节码实现（Javasist）</p>
</li>
</ul>
<p>使用基于接口的动态代理</p>
<p>需要了解的两个类：<code>Proxy</code>（代理），<code>InvocationHandler</code>（调用处理）</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProxyInvocationHandler</span> <span class="keyword">implements</span> <span class="title">InvocationHandler</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//被代理的接口</span></span><br><span class="line">    <span class="keyword">private</span> Rent rent;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setRent</span><span class="params">(Rent rent)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.rent = rent;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//生成得到代理类</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">getProxy</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> Proxy.newProxyInstance(<span class="keyword">this</span>.getClass().getClassLoader(), rent.getClass().getInterfaces(), <span class="keyword">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//处理代理实例，并返回结果</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">invoke</span><span class="params">(Object o, Method method, Object[] args)</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">        <span class="comment">//反射实现</span></span><br><span class="line">        Object result = method.invoke(rent, args);</span><br><span class="line">        fee();</span><br><span class="line">        sign();</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fee</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"收小费"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sign</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"签合同"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//真实角色</span></span><br><span class="line">        Host host = <span class="keyword">new</span> Host();</span><br><span class="line">        <span class="comment">//代理角色（不存在）</span></span><br><span class="line">        ProxyInvocationHandler proxyInvocationHandler = <span class="keyword">new</span> ProxyInvocationHandler();</span><br><span class="line">        <span class="comment">//通过调用程序处理角色</span></span><br><span class="line">        proxyInvocationHandler.setRent(host);</span><br><span class="line">        Rent proxy = (Rent) proxyInvocationHandler.getProxy();<span class="comment">// 动态生成</span></span><br><span class="line">        proxy.rent();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="面向切面编程（AOP）"><a href="#面向切面编程（AOP）" class="headerlink" title="面向切面编程（AOP）"></a>面向切面编程（AOP）</h2><p>AOP (Aspect Oriented Programming)意为:面向切面编程，通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。</p>
<p>AOP是OOP的延续,是软件开发中的一个热点，也是Spring框架中的一个重要内容，是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率。</p>

    </div>

    
    
    
      
  <div class="popular-posts-header">相关文章</div>
  <ul class="popular-posts">
    <li class="popular-posts-item">
      <div class="popular-posts-title"><a href="\2020\07\10\Spring\SpringMVC\" rel="bookmark">Spring MVC</a></div>
    </li>
    <li class="popular-posts-item">
      <div class="popular-posts-title"><a href="\2020\07\30\Spring\设计模式\" rel="bookmark">设计模式</a></div>
    </li>
  </ul>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/tags/Spring/" rel="tag"><i class="fa fa-tag"></i> Spring</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/03/21/HotKey/Typora%E5%BF%AB%E6%8D%B7%E9%94%AE/" rel="prev" title="Typora快捷键">
      <i class="fa fa-chevron-left"></i> Typora快捷键
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/03/21/Spring/SpringBoot/" rel="next" title="SpringBoot">
      SpringBoot <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#基础知识"><span class="nav-number">1.</span> <span class="nav-text">基础知识</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#程序的耦合"><span class="nav-number">1.1.</span> <span class="nav-text">程序的耦合</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#工厂模式"><span class="nav-number">1.2.</span> <span class="nav-text">工厂模式</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring介绍"><span class="nav-number">2.</span> <span class="nav-text">Spring介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#侵入式概念"><span class="nav-number">3.</span> <span class="nav-text">侵入式概念</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#侵入式"><span class="nav-number">3.1.</span> <span class="nav-text">侵入式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#非侵入式"><span class="nav-number">3.2.</span> <span class="nav-text">非侵入式</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring-IoC的概念"><span class="nav-number">4.</span> <span class="nav-text">Spring IoC的概念</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring-IoC-概述"><span class="nav-number">4.1.</span> <span class="nav-text">Spring IoC 概述</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring-IoC容器"><span class="nav-number">4.2.</span> <span class="nav-text">Spring IoC容器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#BeanFactory"><span class="nav-number">4.3.</span> <span class="nav-text">BeanFactory</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#容器的初始化和依赖注入"><span class="nav-number">4.4.</span> <span class="nav-text">容器的初始化和依赖注入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Bean的生命周期"><span class="nav-number">4.5.</span> <span class="nav-text">Bean的生命周期</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#装配Spring-Bean"><span class="nav-number">5.</span> <span class="nav-text">装配Spring Bean</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#依赖注入的3种方式"><span class="nav-number">5.1.</span> <span class="nav-text">依赖注入的3种方式</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#构造器注入"><span class="nav-number">5.1.1.</span> <span class="nav-text">构造器注入</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#setter方法注入"><span class="nav-number">5.1.2.</span> <span class="nav-text">setter方法注入</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#三种注入方式的比较"><span class="nav-number">5.1.3.</span> <span class="nav-text">三种注入方式的比较</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#装配Bean概述"><span class="nav-number">5.2.</span> <span class="nav-text">装配Bean概述</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#通过XML配置装配Bean"><span class="nav-number">5.3.</span> <span class="nav-text">通过XML配置装配Bean</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#装配简易值"><span class="nav-number">5.3.1.</span> <span class="nav-text">装配简易值</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#装配集合"><span class="nav-number">5.3.2.</span> <span class="nav-text">装配集合</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命名空间装配"><span class="nav-number">5.3.3.</span> <span class="nav-text">命名空间装配</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#通过注解装配Bean"><span class="nav-number">5.4.</span> <span class="nav-text">通过注解装配Bean</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#使用-Component装配Bean"><span class="nav-number">5.4.1.</span> <span class="nav-text">使用@Component装配Bean</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#自动装配——-Autowired"><span class="nav-number">5.4.2.</span> <span class="nav-text">自动装配——@Autowired</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring模块"><span class="nav-number">5.5.</span> <span class="nav-text">Spring模块</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring-Core模块"><span class="nav-number">5.6.</span> <span class="nav-text">Spring Core模块</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#HelloSpirng"><span class="nav-number">6.</span> <span class="nav-text">HelloSpirng</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#applicationContext-xml的配置"><span class="nav-number">7.</span> <span class="nav-text">applicationContext.xml的配置</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#别名"><span class="nav-number">7.1.</span> <span class="nav-text">别名</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Bean的配置"><span class="nav-number">7.2.</span> <span class="nav-text">Bean的配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#import"><span class="nav-number">7.3.</span> <span class="nav-text">import</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#依赖注入（DI）"><span class="nav-number">8.</span> <span class="nav-text">依赖注入（DI）</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#构造器注入-1"><span class="nav-number">8.1.</span> <span class="nav-text">构造器注入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Set方式注入"><span class="nav-number">8.2.</span> <span class="nav-text">Set方式注入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#拓展方式注入"><span class="nav-number">8.3.</span> <span class="nav-text">拓展方式注入</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Bean作用域"><span class="nav-number">9.</span> <span class="nav-text">Bean作用域</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#singleton单例模式"><span class="nav-number">9.1.</span> <span class="nav-text">singleton单例模式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#prototype原型模式"><span class="nav-number">9.2.</span> <span class="nav-text">prototype原型模式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#其余"><span class="nav-number">9.3.</span> <span class="nav-text">其余</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Bean的自动装配"><span class="nav-number">10.</span> <span class="nav-text">Bean的自动装配</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#ByName"><span class="nav-number">10.1.</span> <span class="nav-text">ByName</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ByType"><span class="nav-number">10.2.</span> <span class="nav-text">ByType</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#注解"><span class="nav-number">10.3.</span> <span class="nav-text">注解</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#使用注解开发"><span class="nav-number">11.</span> <span class="nav-text">使用注解开发</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#前提配置bean"><span class="nav-number">11.1.</span> <span class="nav-text">前提配置bean</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#属性注入"><span class="nav-number">11.2.</span> <span class="nav-text">属性注入</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#衍生的注解"><span class="nav-number">11.3.</span> <span class="nav-text">衍生的注解</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#自动装配"><span class="nav-number">11.4.</span> <span class="nav-text">自动装配</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#作用域"><span class="nav-number">11.5.</span> <span class="nav-text">作用域</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#小结"><span class="nav-number">11.6.</span> <span class="nav-text">小结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#使用Java的方式配置Bean"><span class="nav-number">12.</span> <span class="nav-text">使用Java的方式配置Bean</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#设计模式"><span class="nav-number">13.</span> <span class="nav-text">设计模式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#静态代理"><span class="nav-number">13.1.</span> <span class="nav-text">静态代理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#动态代理"><span class="nav-number">13.2.</span> <span class="nav-text">动态代理</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#面向切面编程（AOP）"><span class="nav-number">14.</span> <span class="nav-text">面向切面编程（AOP）</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Lanqilu"
      src="http://img.whl123456.top/image/avatar.jpg">
  <p class="site-author-name" itemprop="name">Lanqilu</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">85</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">18</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">39</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/lanqilu" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;lanqilu" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=zqKvoL_noruOqKG2o6_nouCtoaM" title="E-Mail → http:&#x2F;&#x2F;mail.qq.com&#x2F;cgi-bin&#x2F;qm_share?t&#x3D;qm_mailme&amp;email&#x3D;zqKvoL_noruOqKG2o6_nouCtoaM" rel="noopener" target="_blank"><i class="fa fa-fw fa-envelope"></i></a>
      </span>
  </div>



      </div>
        <div class="back-to-top motion-element">
          <i class="fa fa-arrow-up"></i>
          <span>0%</span>
        </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 2019 – 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Lanqilu</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/pjax/pjax.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>

  <script>
var pjax = new Pjax({
  selectors: [
    'head title',
    '#page-configurations',
    '.content-wrap',
    '.post-toc-wrap',
    '.languages',
    '#pjax'
  ],
  switches: {
    '.post-toc-wrap': Pjax.switches.innerHTML
  },
  analytics: false,
  cacheBust: false,
  scrollTo : !CONFIG.bookmark.enable
});

window.addEventListener('pjax:success', () => {
  document.querySelectorAll('script[data-pjax], script#page-configurations, #pjax script').forEach(element => {
    var code = element.text || element.textContent || element.innerHTML || '';
    var parent = element.parentNode;
    parent.removeChild(element);
    var script = document.createElement('script');
    if (element.id) {
      script.id = element.id;
    }
    if (element.className) {
      script.className = element.className;
    }
    if (element.type) {
      script.type = element.type;
    }
    if (element.src) {
      script.src = element.src;
      // Force synchronous loading of peripheral JS.
      script.async = false;
    }
    if (element.dataset.pjax !== undefined) {
      script.dataset.pjax = '';
    }
    if (code !== '') {
      script.appendChild(document.createTextNode(code));
    }
    parent.appendChild(script);
  });
  NexT.boot.refresh();
  // Define Motion Sequence & Bootstrap Motion.
  if (CONFIG.motion.enable) {
    NexT.motion.integrator
      .init()
      .add(NexT.motion.middleWares.subMenu)
      .add(NexT.motion.middleWares.postList)
      .bootstrap();
  }
  NexT.utils.updateSidebarPosition();
});
</script>




  




  
<script src="/js/local-search.js"></script>













    <div id="pjax">
  

  

  

    </div>
</body>
</html>
